﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WaveEngine.Extensions.ITasks;
using WaveEngine.Framework;
using WaveEngine.Framework.Animation;
using WaveEngine.Framework.Graphics;

namespace WaveEngine.Extensions.Behaviors
{
    public class ScaleEffectBehavior : Behavior
    {
        [RequiredComponent]
        private Transform2D transform = null;

        private TimeSpan timer;
        private bool isScaleIn;

        public TimeSpan Duration { get; set; }
        public IEasingFunction EasingFunction { get; set; }
        public float MaxScale { get; set; }
        public float MinScale { get; set; }

        public ScaleEffectBehavior(TimeSpan duration)
        {
            this.Duration = duration;
            this.MaxScale = 1;
            this.MinScale = 0;
            this.IsActive = false;
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void Update(TimeSpan gameTime)
        {
            if (this.timer >= this.Duration)
            {
                if (this.isScaleIn)
                {
                    this.transform.XScale = this.MaxScale;
                    this.transform.YScale = this.MaxScale;
                }
                else
                {
                    this.transform.XScale = this.MinScale;
                    this.transform.YScale = this.MinScale;
                }

                this.timer = TimeSpan.Zero;
                this.isScaleIn = !this.isScaleIn;
                this.IsActive = false;
                return;
            }

            float elapsedTime = (float)(this.timer.TotalSeconds / this.Duration.TotalSeconds);

            if (this.EasingFunction != null)
            {
                elapsedTime = (float)this.EasingFunction.Ease(elapsedTime);
            }

            float scaleValue;
            if (this.isScaleIn)
            {
                scaleValue = this.MinScale + (this.MaxScale - this.MinScale) * elapsedTime;
            }
            else
            {
                scaleValue = this.MinScale + (this.MaxScale - this.MinScale) * (1 - elapsedTime);
            }

            this.transform.XScale = scaleValue;
            this.transform.YScale = scaleValue;

            this.timer += gameTime;
        }

        public ITask CreateScaleInTask()
        {
            return this.Owner.Scene.CreateActionTask(() =>
            {
                this.isScaleIn = true;
                this.timer = TimeSpan.Zero;
                this.IsActive = true;
            })
            .AndWaitConditionActively(() => !this.IsActive);
        }

        public ITask CreateScaleOutTask()
        {
            return this.Owner.Scene.CreateActionTask(() =>
            {
                this.isScaleIn = false;
                this.timer = TimeSpan.Zero;
                this.IsActive = true;
            })
            .AndWaitConditionActively(() => !this.IsActive);
        }
    }
}
